home *** CD-ROM | disk | FTP | other *** search
- /*************************************************
- * Name : lightpen
- * This code installs a lightpendriver as an
- * InputEvent-Handler.
- * Left Mousebutton on Pin 3
- * Right Mousebutton on Pin 4
- *
- * For SAS/C compile with -v
- * (no stack checking)
- *
- * © Copyright by Andreas Klingler 1988,1991
- *
- * This program is freely distributable but is NOT public domain.
- * It MAY NOT be included in any commercial package, or sold for
- * ANY amount, without written permission from the author.
- * However if may be included on any freely distributable package,
- * including packages for which a nominal copying fee of no more than
- * $5 is charged, as long as this copyright notice keeps intact.
- * This software is distributed as-is, without any warranty.
- *
- * created 31.10.88 akk
- * cleanup 27.01.91 akk
- *************************************************/
- #include <exec/types.h>
- #include "intuition/intuition.h"
- #include <exec/ports.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <devices/input.h>
- #include <exec/devices.h>
- #include <devices/inputevent.h>
- #include "stdio.h"
- #include "stdlib.h"
- #include "graphics/gfxbase.h"
- #include "graphics/view.h"
- #include "proto/dos.h"
- #include "proto/exec.h"
- #include "proto/intuition.h"
- #include "proto/graphics.h"
- #include "hardware/custom.h"
-
- /***************** CONSTANTS ********************/
- #define LP_ENABLE 0x08
- #define XCOMPENSATE 42 /* This is to compensate some timing problems.
- You might need to change this. Uh! Again the
- answer is 42! What was the question!? */
-
- #define BANNER "\x9B\x30;33mLightpenhandler Version 1.1\x9B\x30m © by Andreas Klingler 1988,1991\n"
- #define ACTIVATED " Handler installed\n"
- #define TERMINATING " Handler removed\n"
- #define PORTNAME "lightpen_AKK.port"
-
- /****************** GLOBAL VARIABLES ************/
- extern struct Custom __far custom;
-
- struct MsgPort *inputDevPort;
- struct IOStdReq *inputRequestBlock;
- struct Interrupt handlerStuff;
- struct OURMSG {
- struct Message msgpart;
- short dummy;
- } msg;
-
- struct LpInfo { short *ViewX, *ViewY; } handlerdata;
-
- /* Prototypes for functions defined in lp.c */
- struct InputEvent * __regargs __saveds myhandler(struct InputEvent *,
- struct LpInfo *);
- void main(void);
- void chkabort(void);
-
-
- /* Declarations for CBACK */
- extern BPTR _Backstdout; /* standard output when run in background */
- long _BackGroundIO = 1; /* Flag to tell it we want to do I/O */
- long _stack = 4000; /* Amount of stack space our task needs */
- char *_procname = "Lightpenhandler"; /* The name of the task to create */
- long _priority = 20; /* The priority to run us at */
-
- /******************* Here goes the Handler ****************/
- struct InputEvent *
- __regargs __saveds myhandler(ev, mydata)
- struct InputEvent *ev; /* and a pointer to a list of events */
- struct LpInfo *mydata; /* system will pass me a pointer to my
- own data space. */
-
- {
- static struct InputEvent lpev;
- struct InputEvent *retwert;
- BOOL lpen_invalid = FALSE,button_pressed = FALSE;
- static BOOL left_down,right_down;
- ULONG pos;
- static ULONG *lpen = (ULONG *)&custom.vposr;
- register short x,y;
-
- pos = *lpen; /* read pen position (we read two
- registers here: VPOSR,VHPOSR) */
-
- Forbid();
- if ((pos != *lpen) || /* Test, if Lpen has been
- triggered since VBLANK */
- ((pos & 0x1ffff) > 0x12a00)) { retwert=ev; lpen_invalid=TRUE; }
- else retwert = &lpev;
-
- /* Translate in HIRES INLACE coordinates (depending of position of
- the View). That`s what mouse coordinates are in.
- Since we have only 8 bits for the horizonal position it gets
- a little bit tricky (there are 640 pixel in one line in hires!) */
- x = (short)((pos <<1) & 0x1ff);
- if (x < 100) x += 454;
- y = ((short) (pos >> 8) &0x1ff) - *(mydata->ViewY);
- x -= (*(mydata->ViewX) + XCOMPENSATE);
-
- lpev.ie_NextEvent = ev; /* link lpen ahead of event stream */
- lpev.ie_Class = IECLASS_POINTERPOS;
- lpev.ie_Code = IECODE_NOBUTTON;
- lpev.ie_Qualifier = 0;
- lpev.ie_TimeStamp.tv_secs = 0;
- lpev.ie_TimeStamp.tv_micro = 0;
- lpev.ie_X = x << 1;
- lpev.ie_Y = y << 1;
-
- /* Button on lightpen pressed ? */
- if (right_down) {
- if (!(custom.joy1dat & 1)) { lpev.ie_Code = IECODE_RBUTTON |
- IECODE_UP_PREFIX;
- right_down = FALSE;
- button_pressed = TRUE;
- }
- }
- else if (custom.joy1dat & 1) { lpev.ie_Code = IECODE_RBUTTON;
- right_down = TRUE;
- button_pressed = TRUE;
- }
- if (left_down) {
- if (!(custom.joy1dat & 0x100)){
- lpev.ie_Code = IECODE_LBUTTON |
- IECODE_UP_PREFIX;
- left_down = FALSE;
- button_pressed = TRUE;
- }
- }
- else if (custom.joy1dat & 0x100) {
- lpev.ie_Code = IECODE_LBUTTON;
- left_down = TRUE;
- button_pressed = TRUE;
- }
-
- /* Append positiondata only if it is valid */
- if (button_pressed && lpen_invalid) {
- lpev.ie_Class = IECLASS_RAWMOUSE;
- lpev.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE;
- lpev.ie_X = lpev.ie_Y = 0;
- retwert = &lpev;
- }
- Permit();
- return (retwert);
- }
-
-
- void main()
- {
- struct MsgPort *port;
- SHORT error;
-
-
- if (_Backstdout) Write(_Backstdout, BANNER, sizeof(BANNER));
-
- /* now see if we are allready installed */
- if (!(port = FindPort(PORTNAME))) {
- /* if not, install ourself : */
- if ((port = CreatePort(PORTNAME,0)) == NULL) _exit (19);
-
- GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
- if (!GfxBase) _exit(20);
-
- IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
- if (!IntuitionBase) _exit(21);
-
- /* Tell the OS about the lightpen and enable the hardware */
- GfxBase->system_bplcon0 |= LP_ENABLE;
- RemakeDisplay();
-
- /* Determine position of the View. Attention: if someone pokes
- around with Preferences while we are running, we can`t handle
- this! */
- handlerdata.ViewX = (short *)&(GfxBase->ActiView->DxOffset);
- handlerdata.ViewY = (short *)&(GfxBase->ActiView->DyOffset);
-
- inputDevPort = CreatePort(0,0); /* for input device */
- if(inputDevPort == NULL) _exit(1); /* error during createport */
- inputRequestBlock=CreateStdIO(inputDevPort);
- if(inputRequestBlock == 0) { DeletePort(inputDevPort); _exit(2); }
- /* error during createstdio */
-
-
- handlerStuff.is_Data = (APTR)&handlerdata;
- /* address of its data area */
- handlerStuff.is_Code = (void *)myhandler;
- /* address of entry point to handler */
- handlerStuff.is_Node.ln_Pri = 51;
- /* set the priority one step higher than
- * Intuition, so that our handler enters
- * the chain ahead of Intuition.
- */
- error = OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0);
- if(error) _exit(23);
-
- inputRequestBlock->io_Command = IND_ADDHANDLER;
- inputRequestBlock->io_Data = (APTR)&handlerStuff;
-
- DoIO((struct IORequest *)inputRequestBlock); /* Activate the Handler */
-
- /* The Handler is running. Close everything we don`t need
- anymore and wait until it is time to uninstall the handler.
- All the dirty work is done by the handler */
-
- CloseLibrary((struct Library *)IntuitionBase);
- CloseLibrary((struct Library *)GfxBase);
-
- if (_Backstdout) { Write(_Backstdout,ACTIVATED, sizeof(ACTIVATED));
- Close(_Backstdout);
- }
- WaitPort(port); /* Wait until we get message */
- GetMsg(port); /* to exit, then remove it */
- /* and get out */
-
- inputRequestBlock->io_Command = IND_REMHANDLER;
- inputRequestBlock->io_Data = (APTR)&handlerStuff;
- DoIO((struct IORequest *)inputRequestBlock);
-
- /* close the input device */
- CloseDevice((struct IORequest *)inputRequestBlock);
-
- /* delete the IO request */
- DeleteStdIO(inputRequestBlock);
-
- /* free other system stuff */
- DeletePort(inputDevPort);
- DeletePort(port);
- } /* this is the end of the BIG-IF (and of the program */
-
- else /* in this case the handler is already installed, so we
- send a message to it to make it deinstall itself */
- {
- msg.msgpart.mn_Length = sizeof(struct OURMSG);
- PutMsg(port,(struct Message *)&msg);
- if (_Backstdout) { Write(_Backstdout, TERMINATING, sizeof(TERMINATING));
- Close(_Backstdout);
- }
- }
- } /* end of main */
-
- void MemCleanup() {} /* We don`t want this out of lc.lib */
-
- void chkabort() {}